﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Windows.Interop;

namespace ComToolkit.Data
{
    //MSDN: http://msdn.microsoft.com/en-us/library/ms675841%28VS.85%29.aspx
    public class AdoDataReader : DynamicObject, IDisposable
    {
        private dynamic reader;

        internal AdoDataReader(dynamic reader)
        {
            this.reader = reader;
            if (!reader.EOF && reader.Fields != null && reader.Fields.Count > 0)
            {
                int cols = (int)reader.Fields.Count;
                Columns = new string[cols];
                for (int i = 0; i < cols; i++)
                {
                    Columns[i] = (string)reader.Fields[i].Name;
                }
            }

        }

        public long RecordCount
        {
            get { return reader.RecordCount; }
        }

        public T GetColumn<T>(int index)
        {
            return (T)this[index];
        }

        public T GetColumn<T>(string name)
        {
            return (T)this[name];
        }

        public object this[int index]
        {
            get
            {
                return (object)reader.Fields[index].Value;
            }
        }

        public object this[string key]
        {
            get
            {
                return (object)reader.Fields[key].Value; ;
            }
        }

        public override bool TryGetMember(
            GetMemberBinder binder, out object result)
        {
            result = this[binder.Name];
            return true;
        }

        public string[] Columns { get; private set; }

        public IEnumerable<Dictionary<string, object>> GetRows()
        {
            List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
            //object[] rows = reader.GetRows(rows:- 1, start: 0);
            //dynamic[] rows = reader.GetRows();
            while (Read())
            {
                Dictionary<string, object> row = new Dictionary<string, object>();
                //dynamic r = reader.GetChildren();
                for (int i = 0; i < Columns.Length; i++)
                {

                    row.Add(Columns[i], this[Columns[i]]);
                }
                rows.Add(row);
            }
            return rows;
        }

        bool first = true;
        public bool Read()
        {
            //TODO: Is there any peek like functionallity?
            if (reader.EOF)
                return false;
            if (first)
                first = false;
            else
                reader.MoveNext();
            if (reader.EOF)
                return false;
            return true;
        }

        public void Dispose()
        {
            reader.Close();
            reader = null;
        }
    }
}
